package com.zk.cq.handler;

import com.alibaba.fastjson.JSONObject;
import com.zk.cq.annotation.Listener;
import com.zk.cq.annotation.RobotListeners;
import com.zk.cq.constant.ListenerContext;
import com.zk.cq.constant.PostTypes;
import com.zk.cq.constant.RobotType;
import com.zk.cq.constant.TypeToParam;
import com.zk.cq.model.bo.BeanMethodBO;
import com.zk.cq.util.FilterKeywordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

/**
 * 根事件处理
 */
@Slf4j
@Service
public class DispatcherHandler {

    public static Object handler(JSONObject param) throws InvocationTargetException, IllegalAccessException {
        String postType = param.getString(RobotType.POST_TYPE);
        Map<String, List<BeanMethodBO>> postMaps = ListenerContext.POST_TYPE_CONTEXT.get(postType);
        List<BeanMethodBO> methods = null;
        if (PostTypes.MESSAGE.equals(postType)){
            methods = postMaps.get(param.getString(RobotType.MESSAGE_TYPE));
        } else if(PostTypes.NOTICE.equals(postType)){
            methods = postMaps.get(param.getString(RobotType.NOTICE_TYPE));
        } else if(PostTypes.REQUEST.equals(postType)){
            methods = postMaps.get(param.getString(RobotType.REQUEST_TYPE));
        } else if(PostTypes.META_EVENT.equals(postType)){
            methods = postMaps.get(param.getString(RobotType.META_EVENT_TYPE));
        }

        if (PostTypes.REQUEST.equals(postType)) {
            if (!CollectionUtils.isEmpty(methods)) {
                BeanMethodBO beanMethodBO = methods.get(0);
                return beanMethodBO.getMethod().invoke(
                        beanMethodBO.getBean(),
                        param.toJavaObject(
                                TypeToParam.getParamClass(
                                        beanMethodBO.getBean().getClass().getAnnotation(RobotListeners.class).postType(),
                                        beanMethodBO.getMethod().getAnnotation(Listener.class).value())
                        ));
            }
        } else {
            for (BeanMethodBO beanMethodBO : methods) {
                beanMethodBO.getMethod().invoke(
                        beanMethodBO.getBean(),
                        param.toJavaObject(
                                TypeToParam.getParamClass(
                                        beanMethodBO.getBean().getClass().getAnnotation(RobotListeners.class).postType(),
                                        beanMethodBO.getMethod().getAnnotation(Listener.class).value())
                        ));
            }
        }
        return null;
    }
}
